package com.cbi.portal.utils.content;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

public class ContentCollection {
    public ContentCollection() {
        super();
    }

    public ContentCollection(List contentItems) {
        this.contentItems = contentItems;
    }
    
    public ContentCollection(List contentItems, Integer rowsPerPage) {
        this.contentItems = contentItems;
        this.rowsPerPage = rowsPerPage;
    }    
    
    private List contentItems;
    private Integer currentPage = 1;
    private Integer rowsPerPage = 10;
    private Integer totalNumberOfpages;
    private Integer totalRowsFetched;
    private List currentPageContentItems;
    // Page indexes that has to appear between Prev and Next links (excluding first & last page index)
    private List<Integer> currPageIndexes;
    private Boolean showPrevDots;
    private Boolean showAfterDots;
    //Number of page navigable page indexes that have to shown on the UI (excluding first & last page index)
    private int numOfDispPageIndexes = 3;
    private Integer lastDispIndex;
    private List<SelectItem> rowsPerPageSOC;
    private List<SelectItem> sortBySOC;
    private Integer firstPageIndex = 1;

    public List getCurrentPageContentItems() {
        if (currentPageContentItems == null) {
            currentPageContentItems = new ArrayList();
            Integer rangeFromIndex = (currentPage - 1) * rowsPerPage;
            if(rowsPerPage != null && rowsPerPage.intValue() == -1)
                rowsPerPage = getTotalRowsFetched();
            Integer rangeToIndex =
                currentPage * rowsPerPage > getTotalRowsFetched() ?
                getTotalRowsFetched() : currentPage * rowsPerPage;
            for (Integer i = rangeFromIndex; i < rangeToIndex; i++) {
                currentPageContentItems.add(getContentItems().get(i.intValue()));
            }
        }

        return currentPageContentItems;
    }

    private void resetPage() {
        currentPageContentItems = null;
        currPageIndexes = null;
        showAfterDots = null;
        showPrevDots = null;
    }

    public void onPageNumberAction(ActionEvent actionEvent) {
        // Add event code here...
        Integer pageNumber =
            (Integer)actionEvent.getComponent().getAttributes().get("pageNumber");
        currentPage = pageNumber;
        resetPage();
    }

    public void onPrevPageAction(ActionEvent actionEvent) {
        // Add event code here...
        if (currentPage > 1) {
            --currentPage;
            resetPage();
        }
    }

    public void onNextPageAction(ActionEvent actionEvent) {
        // Add event code here...
        if (currentPage < getTotalNumberOfpages()) {
            ++currentPage;
            resetPage();
        }
    }

    public boolean isPrevLinkEnabled() {
        if (currentPage > 1)
            return false;
        else
            return true;
    }

    public boolean isNextLinkEnabled() {
        if (currentPage < getTotalNumberOfpages())
            return false;
        else
            return true;
    }

    public void setTotalRowsFetched(Integer totalRowsFetched) {
        this.totalRowsFetched = totalRowsFetched;
    }

    public Integer getTotalRowsFetched() {
        if (totalRowsFetched == null)
            totalRowsFetched =
                    getContentItems() != null ? getContentItems().size() : 0;
        return totalRowsFetched;
    }

    public void onDisplayRowsPerPageValueChange(ValueChangeEvent valueChangeEvent) {
        // Add event code here...
        if (valueChangeEvent.getNewValue() != null) {
            currentPage = 1;
            rowsPerPage = (Integer)valueChangeEvent.getNewValue();
            if(rowsPerPage != null && rowsPerPage.intValue() == -1){
                rowsPerPage = getTotalRowsFetched();
            }
            totalNumberOfpages = null;
            resetPage();
        }
    }


    public Integer getTotalNumberOfpages() {

        int listSize = getTotalRowsFetched();
        if (listSize == 0) {
            totalNumberOfpages = 1;
        } else {
            int q = listSize % getRowsPerPage();
            if (q == 0) {
                totalNumberOfpages = listSize / getRowsPerPage();
            } else {
                totalNumberOfpages = (listSize / getRowsPerPage()) + 1;
            }
        }
        return totalNumberOfpages;
    }


    public void setContentItems(List contentItems) {
        this.contentItems = contentItems;
    }

    public List getContentItems() {
        return contentItems;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPageContentItems(List currentPageContentItems) {
        this.currentPageContentItems = currentPageContentItems;
    }


    public void setRowsPerPage(Integer rowsPerPage) {
        this.rowsPerPage = rowsPerPage;
    }

    public Integer getRowsPerPage() {
        return rowsPerPage;
    }

    public void setCurrPageIndexes(List<Integer> currPageIndexes) {
        this.currPageIndexes = currPageIndexes;
    }

    public List<Integer> getCurrPageIndexes() {
        if (currPageIndexes == null) {
            currPageIndexes = new ArrayList<Integer>();

            Integer fromPage = null;
            if (getLastDispIndex() == getTotalNumberOfpages()) {
                // when num of pages less than num of disp pages
                if (getLastDispIndex() < numOfDispPageIndexes)
                    fromPage = 1;
                else
                    fromPage = getLastDispIndex() - numOfDispPageIndexes + 1;
            } else
                fromPage = currentPage;

            Integer toPage = getLastDispIndex();

            for (int i = fromPage.intValue(); i <= toPage.intValue(); i++)
                currPageIndexes.add(i);
        }
        return currPageIndexes;
    }

    //    public void setPageNumbersBeforeNext(List<Integer> pageNumbersAfterDots) {
    //        this.pageNumbersBeforeNext = pageNumbersAfterDots;
    //    }
    //
    //    public List<Integer> getPageNumbersBeforeNext() {
    //        return pageNumbersBeforeNext;
    //    }

    //    public void setShowPrevDots(Boolean showPageNumbersBeforeDots) {
    //        this.showPrevDots = showPageNumbersBeforeDots;
    //    }

    public Boolean getShowPrevDots() {
        if (showPrevDots == null) {
            if (currentPage > 1 &&
                getTotalNumberOfpages() > numOfDispPageIndexes)
                showPrevDots = Boolean.TRUE;
            else
                showPrevDots = Boolean.FALSE;
        }
        return showPrevDots;
    }

    //    public void setShowAfterDots(Boolean showPageNumbersAfterDots) {
    //        this.showAfterDots = showPageNumbersAfterDots;
    //    }

    public Boolean getShowAfterDots() {
        if (showAfterDots == null) {
            if (getLastDispIndex() < getTotalNumberOfpages())
                showAfterDots = Boolean.TRUE;
            else
                showAfterDots = Boolean.FALSE;
        }
        return showAfterDots;
    }

    public Integer getLastDispIndex() {

        lastDispIndex =
                currentPage + numOfDispPageIndexes - 1 > getTotalNumberOfpages() ?
                getTotalNumberOfpages() :
                currentPage + numOfDispPageIndexes - 1;

        return lastDispIndex;
    }

    public List<SelectItem> getRowsPerPageSOC() {
        if (rowsPerPageSOC == null) {
            SelectItem rows10 = new SelectItem("10", "10");
            SelectItem rows20 = new SelectItem("20", "20");
            SelectItem rows30 = new SelectItem("30", "30");
            rowsPerPageSOC = new ArrayList<SelectItem>();
            rowsPerPageSOC.add(rows10);
            rowsPerPageSOC.add(rows20);
            rowsPerPageSOC.add(rows30);
        }

        return rowsPerPageSOC;
    }

    public List<SelectItem> getSortBySOC() {
        //        if (sortBySOC == null) {
        //            SelectItem id = new SelectItem("view.SortById", "Id");
        //            SelectItem name = new SelectItem("ConentName", "ConentName");
        //            SelectItem grp = new SelectItem("ContentGroup", "ContentGroup");
        //            sortBySOC = new ArrayList<SelectItem>();
        //            sortBySOC.add(id);
        //            sortBySOC.add(name);
        //            sortBySOC.add(grp);
        //        }
        return sortBySOC;
    }

    public void onSortByValueChange(ValueChangeEvent valueChangeEvent) {
        // TODO
        if (valueChangeEvent.getNewValue() != null) {
            String sortCriteria = (String)valueChangeEvent.getNewValue();
            try {
                Collections.sort(contentItems,
                                 (Comparator)Class.forName(sortCriteria).newInstance());
            } catch (Exception e) {
            }
            currentPage = 1;
            resetPage();
        }
    }

    public Integer getFirstPageIndex() {
        return firstPageIndex;
    }

    public void setSortBySOC(List<SelectItem> sortBySOC) {
        this.sortBySOC = sortBySOC;
    }
}
